// $Id: spaceship.h 527 2008-06-02 00:14:11Z agjermun $
// Simple spaceship class, test of the baseworldobject class
//
// ml278
// Copyright (C) 2008 Bjørn Øivind Bjørnsen, Aleksander Gjermundsen, Knut Andre Tidemann, Thomas Hansen
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#ifndef __SPACESHIP_H
#define __SPACESHIP_H

#include "Ogre.h"
#include "baseworldobject.h"
#include "colshapemanager.h"

using namespace Ogre;

/**
 * A simple spaceship implementation.
 * Provides a set of simple functions for the different movement directions (pitch, yaw, roll).
*/
class SpaceShip : public BaseWorldObject
{
	private:
		static const int NUM_MOVEMENT_DIRS = 8;		/**< Numer of possible movement directions, number of elements in the ShipMovement enum */
		ColShapeManager::ColShapeKey *mColKey;		/**< Used for generating and storing the collision shape */
		bool mMovementDir[NUM_MOVEMENT_DIRS];		/**< Bools that indicate that movement i a direction i enabled ("digital input") */
		double mAngularFactor;				/**< Factor in which to turn when turning with mMovementDir */
		double mAngularMaxSpeed;			/**< Maximum speed with which to turn when turning with mMovementDir */

	public:
		SpaceShip(SceneManager *pMgr, SceneNode *pNode, btDynamicsWorld *world, String objectName);
		~SpaceShip();

		enum ShipMovement {FORWARD, BACKWARD, YAW_LEFT, YAW_RIGHT, ROLL_LEFT, ROLL_RIGHT, PITCH_UP, PITCH_DOWN};

		void setPos(Vector3 &pos);
		const Quaternion& getOrientation();

		void setVisible(bool);
		void update(Real elapsedTime);

		/** Returns a normalized vector pointing forward */
		inline btVector3 getZVector()
		{
			btTransform trans;
			trans = mBody->getCenterOfMassTransform();
			btVector3 forwardVector(trans.getBasis()[0][2],
			                        trans.getBasis()[1][2],
			                        trans.getBasis()[2][2]);
			return(forwardVector);
		}

		/** Returns a normalized vector representing the local x-axis (perpendicular to the forwardVector/z-axis) */
		inline btVector3 getYVector()
		{
			btTransform trans;
			trans = mBody->getCenterOfMassTransform();
			btVector3 xVector(trans.getBasis()[0][1],
			                  trans.getBasis()[1][1],
			                  trans.getBasis()[2][1]);
			return(xVector);
		}

		inline btVector3 getXVector()
		{
			btTransform trans;
			trans = mBody->getCenterOfMassTransform();
			btVector3 yVector(trans.getBasis()[0][0],
			                  trans.getBasis()[1][0],
			                  trans.getBasis()[2][0]);
			return(yVector);
		}

		void applyMovementDir(ShipMovement dir);
		void removeMovementDir(ShipMovement dir);

		void fireRollThruster(btScalar &force);
		void firePitchThruster(btScalar &force);
		void fireYawThruster(btScalar &force);

		void fireMainThruster(btScalar &force);
		void fireReverseThruster(btScalar &force);
		
		void turnAngleAroundXAxis(btScalar &angle);
		void turnAngleAroundYAxis(btScalar &angle);
		void turnAngleAroundZAxis(btScalar &angle);

		void initPhysics();
		void exitPhysics();

		void setAngularMaxSpeed(double speed);
		void setAngularFactor(double factor);
		double getAngularMaxSpeed();
		double getAngularFactor();
};

#endif // #ifndef __SPACESHIP_H
